package org.xmap.ui;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import org.xmap.app.Env;
import org.xmap.ui.base.Window;
import org.xmap.ui.base.Event;
import org.xmap.ui.control.Menubar;

public final class UIUtil {

    /**
     * 指定坐标、锚点来绘制字符串。
     * @param g Graphics 图形句柄。
     * @param s String 字符串。
     * @param x int 横坐标。
     * @param y int 纵坐标。
     * @param anchorX int 横方向的锚点。
     * @param anchorY int 纵方向的锚点。
     */
    public static final void draw(Graphics g, String s, int x,
            int y, int anchorX, int anchorY) {
        if (g != null && s != null) {
            if (anchorY == Graphics.VCENTER) {
                g.drawString(s, x, y - (Env.instance.defaultFontHeight >> 1) + Env.instance.defaultFontYOffset, anchorX | Graphics.TOP);
//                g.drawLine(0, y, 320, y);
            } else {
                g.drawString(s, x, y, anchorX | anchorY);
            }
        }
    }

    /**
     * 绘制窗口。
     * @param g Graphics 图形句柄。
     * @param w Window 窗口对象。
     */
    public static final void draw(Graphics g, Window w) {
        if (w.getShow()) {
            g.translate(w.getRect().leftUp.x, w.getRect().leftUp.y);
            if (w.getSetClipBeforeDraw()) {
                int clipX = g.getClipX();
                int clipY = g.getClipY();
                int clipW = g.getClipWidth();
                int clipH = g.getClipHeight();
                g.setClip(0, 0, w.getRect().width, w.getRect().height);
                w.draw(g);
                g.setClip(clipX, clipY, clipW, clipH);
            } else {
                w.draw(g);
            }
            g.translate(-w.getRect().leftUp.x, -w.getRect().leftUp.y);
        }
    }

    /**
     * 按键事件处理函数，不可用或未显示的控件将不被处理。
     * @param flag boolean 是按下还是抬起。
     * @param keyCode int 按键代码。
     * @param gameAction int 动作代码。
     * @param w Window 控件对象。
     * @return boolean 是否处理该事件。
     */
    public static boolean keyEvent(boolean flag, int keyCode, int gameAction, Window w) {
        if (w.getEnable() && w.getShow()) {
            if (w.getCanFocus()) {
                if (w.getFocus()) {
                    return w.keyEvent(flag, keyCode, gameAction);
                }
            } else {
                return w.keyEvent(flag, keyCode, gameAction);
            }
        }
        return false;
    }

    /**
     * 触笔事件处理函数，不可用或未显示的控件将不被处理。
     * @param ev Event 触笔事件。
     * @param w Window 控件对象。
     * @return boolean 是否处理该事件。
     */
    public static boolean pointerEvent(Event ev, Window w) {
        if (w.getEnable() && w.getShow()) {
            if (w instanceof Menubar) {
                return w.pointerEvent(ev);
            } else if (w.getRect().collideWith(ev.param1, ev.param2)) {
                return w.pointerEvent(ev);
            }
        }
        return false;
    }

    /**
     * 简单对图片进行缩放。
     * @param imgSrc Image 原始图片。
     * @param dstW int 新宽度。
     * @param dstH int 新高度。
     * @return Image 缩放后的图片。
     */
    public static Image fastScale(Image imgSrc, int dstW, int dstH) {
        int srcW = imgSrc.getWidth();
        int srcH = imgSrc.getHeight();
        Image tmp = Image.createImage(dstW, srcH);
        Graphics g = tmp.getGraphics();
        int delta = (srcW << 16) / dstW;
        int pos = delta >> 1;
        for (int x = 0; x < dstW; x++) {
            g.setClip(x, 0, 1, srcH);
            g.drawImage(imgSrc, x - (pos >> 16), 0, Graphics.LEFT | Graphics.TOP);
            pos += delta;
        }
        Image dst = Image.createImage(dstW, dstH);
        g = dst.getGraphics();
        delta = (srcH << 16) / dstH;
        pos = delta >> 1;
        for (int y = 0; y < dstH; y++) {
            g.setClip(0, y, dstW, 1);
            g.drawImage(tmp, 0, y - (pos >> 16), Graphics.LEFT | Graphics.TOP);
            pos += delta;
        }
        return dst;
    }

    /**
     * 指定不同的参数从原始图片或图片的某个区域创建新的图片。
     * @param image Image 原始图片。
     * @param x int 指定区域的横坐标。
     * @param y int 指定区域的纵坐标。
     * @param w int 指定区域的宽度。
     * @param h int 指定区域的高度。
     * @param transform int 创建方式。
     * @return Image 新的图片。
     */
    public static Image createImage(Image image, int x, int y, int w, int h, int transform) {
        int[] data = new int[w * h];
        image.getRGB(data, 0, w, x, y, w, h);
        switch (transform) {
            case Sprite.TRANS_NONE:
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_ROT90:
                // todo
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_ROT180:
                UIUtil.trans180(data, w, h);
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_ROT270:
                // todo
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_MIRROR:
                UIUtil.mirrorImage(data, w, h);
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_MIRROR_ROT90:
                // todo
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_MIRROR_ROT180:
                UIUtil.trans180(data, w, h);
                UIUtil.mirrorImage(data, w, h);
                return Image.createRGBImage(data, w, h, true);
            case Sprite.TRANS_MIRROR_ROT270:
                // todo
                return Image.createRGBImage(data, w, h, true);
        }
        return null;
    }

    private static void mirrorImage(int[] data, int w, int h) {
        int tmp;
        for (int i = 0; i < h; i++) {
            int base = i * w;
            for (int j = 0; j < (w >> 1); j++) {
                tmp = data[base + j];
                data[base + j] = data[base + w - 1 - j];
                data[base + w - 1 - j] = tmp;
            }
        }
    }
//    private static void trans90(int[] data, int w, int h) {
//    }

    private static void trans180(int[] data, int w, int h) {
        int tmp;
        for (int i = 0; i < h >> 1; i++) {
            int baseSrc = i * w;
            int baseDes = (h - 1 - i) * w;
            for (int j = 0; j < w; j++) {
                tmp = data[baseSrc + j];
                data[baseSrc + j] = data[baseDes + w - 1 - j];
                data[baseDes + w - 1 - j] = tmp;
            }
        }
        if (h % 2 == 1) { // 如果高度是奇数,中间那行只需要处理一半
            int i = h >> 1;
            int baseSrc = i * w;
            int baseDes = (h - 1 - i) * w;
            for (int j = 0; j < (w >> 1); j++) {
                tmp = data[baseSrc + j];
                data[baseSrc + j] = data[baseDes + w - 1 - j];
                data[baseDes + w - 1 - j] = tmp;
            }
        }
    }
}
